<?php

Raise::load('core.helper.RaiseHelper');
Raise::load('core.io.file.RaiseFile');
Raise::load('core.collection.RaiseCollection');

/**
 * RaiseSettings ini file helper class
 * Loads an ini configuration file
 *
 * @author Sam-Mauris Yong / hellclanner at live dot com
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package phpraise.core.helper.config
 * @since 1.2
 */
class RaiseSettings extends RaiseHelper {

    /**
     * An array containing all settings returned from parse_ini_file()
     * @var array
     */
    private $settings;

    /**
     * The path name to the configuration file
     * @var RaiseFile
     */
    private $file;

    /**
     * Create a new RaiseSettings
     * @param RaiseFile $iniFile (optional) The pathname to the ini configuration file
     */
    public function __construct($file = null){
        if($file && !($file instanceof RaiseFile)){
            $file = new RaiseFile($file);
        }
        $this->file = $file;
        $this->settings = array();
        if($this->file !== null){
            $this->settings = false;
            if($this->file instanceof RaiseFile && $this->file->exists()){
                $this->settings = parse_ini_file($this->file()->pathname(), true);
            }

            if($this->settings === false){
                throw new RaiseFileOperationFailedException('Unable to open and parse the ini configuration file \'' . $this->file() . '\'. The file might be missing or contain invalid characters.');
            }
        }
    }

    /**
     * Get the path name to the configuration file
     * @return RaiseFile
     */
    public function file(){
        return $this->file;
    }

    /**
     * Get the value based on the section and key
     * @param string $section The section in which the key resides.
     * @param string $key (optional) The key which contains the value. If not set, a collection of the entire section is returned
     * @return mixed|RaiseCollection Returns the value fetched or NULL if the key / section is not found.
     */
    public function get($section, $key = null){
        if($key){
            if(array_key_exists($section, $this->settings) && is_array($this->settings[$section]) && array_key_exists($key, $this->settings[$section])){
                $value = $this->settings[$section][$key];
                if(is_array($value)){
                    $value = new RaiseCollection($value);
                }
                return $value;
            }
        }else{
            if(array_key_exists($section, $this->settings) && is_array($this->settings[$section])){
                return new RaiseCollection($this->settings[$section]);
            }
        }
        return null;
    }

    /**
     * Set the value based on the section and key
     * @param string $section The section in which the key resides.
     * @param string $key The key which contains the value.
     * @param mixed $value The value.
     */
    public function set($section, $key, $value){
        if(!array_key_exists($section, $this->settings) || !is_array($this->settings[$section])){
            $this->settings[$section] = array();
        }
        $this->settings[$section][$key] = $value;
    }

    /**
     * Save the configuration to a configuration file
     * @param string $file
     */
    public function save($file = null){
        if(func_num_args() == 1){
            $this->file = $file;
        }
        $f = new RaiseFile($this->file);
        
        $res = array();
        foreach ($this->settings as $key => $val) {
            if (is_array($val)) {
                $res[] = '[' . $key . ']';
                foreach ($val as $skey => $sval)
                    $res[] = $skey. ' = ' . (is_numeric($sval) ? $sval : '"' . $sval . '"');
            }
            else
                $res[] = $key . ' = ' . (is_numeric($val) ? $val : '"' . $val . '"');
        }
        $f->write(implode("\r\n", $res));
        $f->dispose();
    }

}
